package com.tjtt.tdm.util;

import java.util.HashMap;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class WordTool {
	
	public ActiveXComponent applicationWord = null;
    public Dispatch docs = null;
    public HashMap<String, Dispatch> WordBookMarks =null;
    public Dispatch doc = null;
    public Dispatch activeDocument = null;
    public Dispatch bookMarks;
    public Dispatch selectedTable;
    public Dispatch tables;
    private String filePath = "";
    public WordTool(String _filePath)
	{
		filePath = _filePath;
		if (applicationWord == null||applicationWord.m_pDispatch==0) {
			applicationWord = new ActiveXComponent("Word.Application");
			applicationWord.setProperty("Visible", new Variant(false));
			applicationWord.setProperty("DisplayAlerts", new Variant(false));
	  	}
		if (docs == null||docs.m_pDispatch==0) {
		   docs = applicationWord.getProperty("Documents").toDispatch();
		}
	    doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[]{filePath,new Variant(false)},new int[1]).toDispatch();
	    activeDocument = applicationWord.getProperty("ActiveDocument").toDispatch();
	    bookMarks = applicationWord.call(activeDocument, "Bookmarks").toDispatch();
	    tables = applicationWord.call(doc, "Tables").toDispatch();
	}
	
	public void SetBookMarkValue(String strbookmark,String strvalue)
	{
		boolean bookMarksExist = Dispatch.call(bookMarks, "Exists",strbookmark).toBoolean();
		if(bookMarksExist == true){
			Dispatch rangeItem_new = Dispatch.call(bookMarks, "Item",strbookmark).toDispatch();
			Dispatch range_new = Dispatch.call(rangeItem_new, "Range").toDispatch();
			Dispatch.put(range_new,"Text",strvalue);
		}
		int i=1;
		while(true){
			bookMarksExist = Dispatch.call(bookMarks, "Exists",strbookmark+i).toBoolean();
			if (bookMarksExist){
				Dispatch rangeItem_new = Dispatch.call(bookMarks, "Item",strbookmark+i).toDispatch();
				Dispatch range_new = Dispatch.call(rangeItem_new, "Range").toDispatch();
				Dispatch.put(range_new,"Text",strvalue);
			}
			else{
				break;
			}
			i++;
		}
	}

	public void DelBookMark(String strbookmark)
	{
		boolean bookMarksExist = Dispatch.call(bookMarks, "Exists",strbookmark).toBoolean();
		if(bookMarksExist == true){
			Dispatch rangeItem_new = Dispatch.call(bookMarks, "Item",strbookmark).toDispatch();
			Dispatch.call(rangeItem_new, "Delete").toDispatch();
		}
	}
	
	public void BindList(int tableIndex,String xml, int rowIndex, int rowCount,String groups)
	{
		try{
			SetTableIndex(tableIndex);
			BindList(xml,rowIndex,rowCount,groups);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
	}
	
	public void SetTableIndex(int tableIndex)
    {
		selectedTable = Dispatch.call(tables, "Item",tableIndex).toDispatch();
    }
	
	public void DelTableByIndex(int tableIndex){
		Dispatch curtable = Dispatch.call(tables, "Item",tableIndex).toDispatch();
		Dispatch.call(curtable, "Delete");
	}
	
	public void BindList(String xml, int rowIndex, int rowCount, String groups)
    {
		Document document;
		try {
			document = DocumentHelper.parseText(xml);
			List rowList = document.selectNodes("/table/tr");
	        List columnList = document.selectNodes("/table/tr[1]/td");

	        int columnCount = columnList.size();
	        Dispatch row1 = Dispatch.call(selectedTable, "Rows",rowIndex).toDispatch();
	        for (int i = 0; i < rowList.size() - rowCount; i++)
	        {
	        	Dispatch rows = Dispatch.call(selectedTable, "Rows").toDispatch();
	        	Dispatch.call(rows,"Add",row1);
	        }
	        
	        int m = 0;
	        for (int i = 0; i < rowList.size(); i++)
	        {
	        	Element element = (Element)rowList.get(i);
	        	for (int n = 1; n <= columnCount; n++)
	            {
	        		Node node = (Node)document.selectSingleNode("/table/tr[" + (m + 1) + "]/td[" + n + "]");
	        		if (node!=null)
	        		{
	        			String text = node.getText();
	        			Dispatch cell = Dispatch.call(selectedTable, "Cell",m + rowIndex,n).toDispatch();
	        			Dispatch range = Dispatch.call(cell, "Range").toDispatch();
	        			Dispatch.put(range, "Text",text);
	        		}
	            }
	        	m += 1;
	        }
	        
	        if (!groups.equals("")&&groups!=null)
	        {
	            String[] arrays = groups.split(",");
	            for(int i=0;i<arrays.length;i++)
	            {
	            	int column = Integer.parseInt(arrays[i]);
	            	int allcount = rowIndex + rowList.size()-1;
	            	for (int j = allcount; j > 1; j--)
	                {
	            		Dispatch cell1 = Dispatch.call(selectedTable, "Cell",j,column).toDispatch();
	        			Dispatch range1 = Dispatch.call(cell1, "Range").toDispatch();
	        			String text1 = Dispatch.call(range1, "Text").toString();
	        			
	        			Dispatch cell2 = Dispatch.call(selectedTable, "Cell",j - 1,column).toDispatch();
	        			Dispatch range2 = Dispatch.call(cell2, "Range").toDispatch();
	        			String text2 = Dispatch.call(range2, "Text").toString();
	        			
	        			if (text1.equals(text2))
	        			{
	        				Dispatch.put(range2, "Text", "");
	        				Dispatch.call(cell1, "Merge",cell2);
	        			}
	                }
	            }
	        }
	        
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
	
	
	public void InsertRows(int tableIndex,int rowIndex,int count){
		try{
			Dispatch targetTable = Dispatch.call(tables, "Item",tableIndex).toDispatch();
			Dispatch targetRow = Dispatch.call(targetTable, "Rows",rowIndex).toDispatch();
			Dispatch rows = Dispatch.call(targetTable, "Rows").toDispatch();
			for(int i=0;i<count;i++){
	        	Dispatch.call(rows,"Add",targetRow);
			}
		}
		catch(Exception exp){
			InsertRowsByCell(tableIndex,rowIndex,count);
		}
	}
	
	public void InsertRowsByCell(int tableIndex,int rowIndex,int count){
		Dispatch targetTable = Dispatch.call(tables, "Item",tableIndex).toDispatch();
		Dispatch targetRow = Dispatch.call(targetTable, "Cell",rowIndex+1,1).toDispatch();
		Dispatch targetRange = Dispatch.call(targetRow, "Range").toDispatch();
		Dispatch rows = Dispatch.call(targetRange, "Rows").toDispatch();
		for(int i=0;i<count;i++){
        	Dispatch.call(rows,"Add");
		}
	}
	
	public void InsertFontText(String text,float fontsize,int isbold,String align,String isunderline)
	{
		Dispatch rng;
		Dispatch cha = Dispatch.call(activeDocument, "Characters").toDispatch();
		int lenght = Dispatch.call(cha, "Count").toInt()-1;
	    rng = Dispatch.call(activeDocument, "Range",lenght,lenght).toDispatch();
	    Dispatch.put(rng, "Text", text);
	    Dispatch font = Dispatch.call(rng,"Font").toDispatch();
	    Dispatch.call(font,"Size",fontsize);
	    Dispatch.call(font,"Bold",isbold);
	    if (isunderline=="1")
        {
	    	Dispatch.call(font,"Underline",1);
        }
        else
        {
        	Dispatch.call(font,"Underline",0);
        }
        if (align == "center")
        {
        	Dispatch para = Dispatch.call(rng,"ParagraphFormat").toDispatch();
        	Dispatch.call(para,"Alignment",1);
        }
        if (align == "left")
        {
        	Dispatch para = Dispatch.call(rng,"ParagraphFormat").toDispatch();
        	Dispatch.call(para,"Alignment",0);
        }
	}
	
	public void InsertBr()
	{
		Dispatch rng;
		Dispatch cha = Dispatch.call(activeDocument, "Characters").toDispatch();
		int lenght = Dispatch.call(cha, "Count").toInt()-1;
	    rng = Dispatch.call(activeDocument, "Range",lenght,lenght).toDispatch();
	    Dispatch.put(rng, "Text", "\r\n");
	}
	
	public void InsertBreak()
	{
		Dispatch rng;
		Dispatch cha = Dispatch.call(activeDocument, "Characters").toDispatch();
		int lenght = Dispatch.call(cha, "Count").toInt()-1;
	    rng = Dispatch.call(activeDocument, "Range",lenght,lenght).toDispatch();
	    Dispatch.call(rng, "InsertBreak");
	}

	public void CopyTable(int sourceIndex)
	{
		SetTableIndex(sourceIndex);
		Dispatch.call(selectedTable, "Select");
		Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
		Dispatch.call(selection,"Copy");
	}
	
	public void CopyTableUnder(int sourceIndex,int copyCount){
		SetTableIndex(sourceIndex);
		Dispatch.call(selectedTable, "Select");
		Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
		Dispatch.call(selection,"Copy");
		Dispatch tablerange = Dispatch.call(selectedTable, "Range").toDispatch();
		int tableend = Dispatch.get(tablerange, "End").toInt();
		Dispatch rng = Dispatch.call(activeDocument, "Range",tableend+1,tableend+1).toDispatch();
	    Dispatch.put(rng, "Text", "\r\n");
	    Dispatch.call(rng, "Select");
	    selection = Dispatch.call(applicationWord, "Selection").toDispatch();
	    Dispatch.call(selection,"Paste");
	}
	
	public void PasteTable()
	{
		Dispatch rng;
		Dispatch cha = Dispatch.call(activeDocument, "Characters").toDispatch();
		int lenght = Dispatch.call(cha, "Count").toInt()-1;
	    rng = Dispatch.call(activeDocument, "Range",lenght,lenght).toDispatch();
	    Dispatch.call(rng,"Select");
	    Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
		Dispatch.call(selection,"Paste");
	}
	
	public void SetTableText(int tableIndex,int intRowStart,int intColStart,String text)
	{
		try{
			SetTableIndex(tableIndex);
			if (selectedTable!=null)
			{
				Dispatch cell = Dispatch.call(selectedTable, "Cell",intRowStart,intColStart).toDispatch();
				Dispatch rng = Dispatch.call(cell, "Range").toDispatch();
				Dispatch.put(rng, "Text", text);
			}
		}
		catch(Exception exp){
			exp.printStackTrace();
		}
	}
	
	public void SetTableSelect(int tableIndex)
	{
		try{
			SetTableIndex(tableIndex);
			if (selectedTable!=null)
			{
				Dispatch.call(selectedTable, "Select");
			}
		}
		catch(Exception exp){
			exp.printStackTrace();
		}
	}
	
	
	
	public void Merge(int tableIndex,int intRowStart, int intColStart, int intRowEnd, int intColEnd)
	{
		SetTableIndex(tableIndex);
		Dispatch cell1 = Dispatch.call(selectedTable, "Cell",intRowStart,intColStart).toDispatch();
		Dispatch range1 = Dispatch.call(cell1, "Range").toDispatch();
		Dispatch cell2 = Dispatch.call(selectedTable, "Cell",intRowEnd,intColEnd).toDispatch();
		Dispatch range2 = Dispatch.call(cell2, "Range").toDispatch();
		Dispatch.call(cell1, "Merge",cell2);
	}

	public void CombinTableColumn(int tableIndex,int startRow, int rowCount, int column)
	{
		SetTableIndex(tableIndex);
		int rowIndex = startRow + rowCount -1;
        for (int i = rowIndex; i > startRow; i--)
        {
        	Dispatch cell1 = Dispatch.call(selectedTable, "Cell",i,column).toDispatch();
			Dispatch range1 = Dispatch.call(cell1, "Range").toDispatch();
			String text1 = Dispatch.call(range1, "Text").toString();
			
			Dispatch cell2 = Dispatch.call(selectedTable, "Cell",i - 1,column).toDispatch();
			Dispatch range2 = Dispatch.call(cell2, "Range").toDispatch();
			String text2 = Dispatch.call(range2, "Text").toString();
			
			if (text1.equals(text2))
			{
				Dispatch.put(range2, "Text", "");
				Dispatch.call(cell1, "Merge",cell2);
			}
        }
	}
	
	public String GetTableText(int tableIndex,int intRowStart,int intColStart)
	{
		SetTableIndex(tableIndex);
		Dispatch cell = Dispatch.call(selectedTable,"Cell",intRowStart,intColStart).toDispatch();
		Dispatch range = Dispatch.call(cell, "Range").toDispatch();
		String text = Dispatch.call(range, "Text").toString();
		return text;
	}
	
	public void InsertFile(String markName,String url){
		boolean bookMarksExist = Dispatch.call(bookMarks, "Exists",markName).toBoolean();
		if(bookMarksExist == true){
			Dispatch rangeItem_new = Dispatch.call(bookMarks, "Item",markName).toDispatch();
			Dispatch range_new = Dispatch.call(rangeItem_new, "Range").toDispatch();
			Dispatch.call(range_new,"InsertFile",url);
		}
	}
	
	public void InsertFile(String url){
	    Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
	    Dispatch.call(selection,"EndKey",6);
		Dispatch.call(selection,"InsertFile",url);
	}
	
//	public void InsertFile(String url){
//		Dispatch rng;
//		Dispatch cha = Dispatch.call(activeDocument, "Characters").toDispatch();
//		int lenght = Dispatch.call(cha, "Count").toInt()-1;
//	    rng = Dispatch.call(activeDocument, "Range",lenght,lenght).toDispatch();
//	    Dispatch.call(rng,"Select");
//	    Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
//		Dispatch.call(selection,"InsertFile",url);
//	}
	
	public void Save()
	{
		Variant f = new Variant(false);
		Dispatch.call(doc, "Save");
		Dispatch.call(doc, "Close", f);
		applicationWord.invoke("Quit",new Variant[]{});
		doc = null;
	}
	
	public void SavePdf(String pdfPath)
	{
		Variant f = new Variant(false); 
		Dispatch.call(doc,"SaveAs", pdfPath, 17); 
		Dispatch.call(doc, "Save");
		Dispatch.call(doc, "Close", f);
		applicationWord.invoke("Quit",new Variant[]{});
		doc = null;
	}
	
	//查找是否存在字符串，若存在则把要查找的字符串设置好。
	public boolean Find(Dispatch selection,String text)
	{
		Dispatch find=Dispatch.call(selection, "Find").toDispatch();
		Dispatch.put(find, "Text", text);//设置要查找的文本
		Dispatch.put(find,"Forward","True");//向前找
		Dispatch.put(find,"Format","True");//设置格式
		Dispatch.put(find,"Matchcase","True");//大小写匹配
		Dispatch.put(find,"MatchWholeWord","True");//全字匹配
		return Dispatch.call(find,"Execute").getBoolean();//查找并选中
	}
	
	//全文替换,即文章中所有的字符串都被替换,去掉while则替换一次.
	public void WordFindReplace(String oldtext,String newtext)
	{
		Dispatch  selection=Dispatch.get(applicationWord,"Selection").toDispatch();//选定范围或者插入点
		while(Find(selection,oldtext))//全文替换
		{
			Dispatch.put(selection,"Text",newtext);
			Dispatch.call(selection, "MoveRight");
		}
	}
	
	public int[] GetTableIndexByMark(String mark){
		if (IsExistsMark(mark)){
			int[] position = new int[3];
			Dispatch bookmark = Dispatch.call(bookMarks, "Item",mark).toDispatch();
			//Dispatch markrange = Dispatch.call(bookmark, "Range").toDispatch();
			int markend = Dispatch.get(bookmark, "End").toInt();
			int tableCount = Dispatch.get(tables, "Count").toInt();
			Dispatch targetTable = null;
			for(int i=1;i<=tableCount;i++){
				targetTable = Dispatch.call(tables, "Item",i).toDispatch();
				Dispatch tablerange = Dispatch.call(targetTable, "Range").toDispatch();
				int tableend = Dispatch.get(tablerange, "End").toInt();
				if (tableend>markend){
					position[0] = i;
					break;
				}
			}
			int rowCount = Dispatch.get(Dispatch.call(targetTable, "Rows").toDispatch(), "Count").toInt();
			int colCount = Dispatch.get(Dispatch.call(targetTable, "Columns").toDispatch(), "Count").toInt();
			boolean flag = false;
			for(int i=1;i<=rowCount;i++){
				for(int j=1;j<=colCount;j++){
					Dispatch cell = null;
					try{
						cell = Dispatch.call(targetTable, "Cell",i,j).toDispatch();
					}
					catch(Exception exp){
						break;
					}
					Dispatch cellrange = Dispatch.call(cell, "Range").toDispatch();
					int cellend = Dispatch.get(cellrange, "End").toInt();
					if (cellend>markend){
						position[1] = i;
						position[2] = j;
						flag = true;
						break;
					}
				}
				if (flag){
					break;
				}
			}
			return position;
		}
		else{
			return null;
		}
	}
	
	public boolean IsExistsMark(String mark){
		return Dispatch.call(bookMarks, "Exists",mark).toBoolean();
	}
	
	public void CopyRowRange(int tableIndex,int rowIndex,int rowCount,int copyCount){
		try{
			Dispatch targetTable = Dispatch.call(tables, "Item",tableIndex).toDispatch();
			Dispatch targetRow = Dispatch.call(targetTable, "Rows",rowIndex).toDispatch();
			Dispatch rows = Dispatch.call(targetTable, "Rows").toDispatch();
			int sourceIndex = rowIndex;
			int targetIndex = rowIndex+rowCount;
			for(int i=0;i<copyCount;i++){
				for(int j=0;j<rowCount;j++){
					Dispatch sourceRow = Dispatch.call(targetTable, "Rows",sourceIndex+j).toDispatch();
					Dispatch.call(sourceRow, "Select");
					Dispatch selection = Dispatch.call(applicationWord, "Selection").toDispatch();
					Dispatch.call(selection,"Copy");
					
					Dispatch curtargetRow = Dispatch.call(targetTable, "Rows",targetIndex).toDispatch();
					Dispatch.call(curtargetRow, "Select");
					selection = Dispatch.call(applicationWord, "Selection").toDispatch();
				    Dispatch.call(selection,"Paste");
				    targetIndex++;
				}
			}
		}
		catch(Exception exp){
			exp.printStackTrace();
		}
	}
	
	public static void main(String[] args){
    	WordTool wt = new WordTool("d:\\reportmode.doc");
    	wt.CopyRowRange(1,3,6,2);
    	wt.Save();
    }
	

}
